package ru.passivemoney.subscribers;

import java.util.Iterator;
import java.util.Set;

import ru.passivemoney.common.UtilsOrders;
import ru.passivemoney.manage.orders.OrdersHolder;
import ru.passivemoney.strategy.AStrategy;

import com.dukascopy.api.IBar;
import com.dukascopy.api.IOrder;
import com.dukascopy.api.ITick;
import com.dukascopy.api.Instrument;
import com.dukascopy.api.JFException;
import com.dukascopy.api.Period;
/**
 * Родитель семейства классов, основным назначением которых является манипулирование ордерами (закрытие, открытие и т.д) на основе вычисленного прогноза конкретной валютной пары.<br>
 * Объекты данного семейства классов содержат внутри себя объект класса {@link ru.passivemoney.strategy.AStrategy}, который, абстрагируясь от валютной пары, позволяет, собственно, рассчитать прогноз.<br>
 * Основной метод класса - {@link #reactOnBar(Period, IBar, IBar)}, который рассчитывает значение прогноза по пришедшему бару и периоду. Результатом работы метода может являться открытие/редактирование/закрытие ордера.<br>
 * Внимания заслуживает и метод {@link #reactOnTick(ITick)}, который может, например, инициировать сдвиг значения StopLoss определённого ордера.
 * @author artem
 *
 */
public abstract class ASubscriber {
	
	protected Instrument instrument;
	protected AStrategy strategy;
	private Set<Period> periods; // for optimization only
	
	public ASubscriber(Instrument instrument, AStrategy strategy){
		this.instrument = instrument;
		this.strategy = strategy;
		this.periods = strategy.getPeriods();
	}
	
	public void initStrategy(){
		strategy.initProcessors();
	}
	/**
	 * Рассчитывает значение прогноза по пришедшему бару и периоду. Результатом работы метода может являться открытие/редактирование/закрытие ордера
	 * @param period
	 * @param askBar
	 * @param bidBar
	 * @throws JFException
	 */
	public abstract void reactOnBar(Period period, IBar askBar, IBar bidBar) throws JFException;
	
	/**
	 * Сдвигает значение StopLoss, если допускается
	 * @param tick
	 */
	public void reactOnTick(ITick tick){
		Iterator<IOrder> iterator = OrdersHolder.getOpenedOrders(instrument).iterator();
		while(iterator.hasNext()){
			if(UtilsOrders.putOrderToModificationJobs(iterator.next(), tick.getAsk(), tick.getBid())){
				iterator.remove();
			}
		}
		OrdersHolder.releaseFlagForOpenedOrders(instrument);
	}
	
	public Instrument getInstrument() {
		return instrument;
	}

	public Set<Period> getPeriods() {
		return periods;
	}
	
	public AStrategy getStrategy(){
		return null;	
	}
}
